package com.itheima.d3_inner_class3;



/**
 * 局部内部类 局部内部类是定义在在方法中、代码块中、构造器等执行体中。鸡肋语法，看看就好 跳过
 *
 * 匿名内部类
 * 就是一种特殊的局部内部类；所谓匿名：指的是程序员不需要为这个类声明名字。
 * 特点：匿名内部类本质就是一个子类，并会立即创建出一个子类对象。
 * 编译后的class文件在out文件夹下面，可以反编译的看到:匿名内部类是创建了一个子类对象
 *需要注意的是，匿名内部类在编写代码时没有名字，编译后系统会为自动为匿名内部类生产字节码，字节码的名称会以`外部类$1.class`的方法命名
 *
 * 作用：
 * 用于更方便的创建一个子类对象。
 * 匿名内部类通常作为一个参数传输给方法。
 * 都是有需要的时候才会被使用，调用别人的API
 *
 * 写法：
 * new  类或接口(参数值…) {
 * 类体(一般是方法重写)；
 * };
 *
 */


public class Test {
    public static void main(String[] args) {
/**
         * 在开发中有时只需创建一个子类对象使用一次就好了，并不用经常创建这个子类对象
         * 但是此时为了创建这个子类对象，还需要单独创建一个子类（例如这次的cat）类出来就显得麻烦
         * 所以为了用更方便的方式去得到一个父类animal的子类对象，匿名内部类就是为此而生的
         *
 * 匿名内部类不需要定义一个子类，他有一个机制是可以直接得到子类对象
        Animal a1 = new Cat();
        a1.cry();

        Cat a2 = new Cat();
        a2.cry();
*/

/*
        // 目标：认识匿名内部类，并掌握其作用。
        // 1、计算机看到这个代码，首先会把这个匿名内部类编译成一个子类，然后会立即创建一个子类对象出来。
          这就是一个子类，也是一个子类对象，要交给一个变量来记住
        new Animal(){
            @Override
            public void cry() {
                System.out.println("猫喵喵喵的叫~~~");
            }
        };
        */

        //这里后面new 的部分，其实就是一个Animal的子类对象
        //这里隐含的有多态的特性： Animal a = Animal子类对象;
        Animal a = new Animal() {    //（因为此时的匿名内部类就是animal的一个子类,交给了变量a来记住）
            @Override
            public void cry() {
                System.out.println("猫喵喵喵的叫~~~");
            }
        };
        a.cry();

        //上面的简化写法如下：
        new Animal(){
            @Override
            public void cry() {
                System.out.println("匿名内部类不作为参数，作为一个子类对象调用重写的方法使用");
            }
        }.cry();
    }
}

/*
有了匿名内部类，就不需要频繁定义一个子类出来
class Cat extends Animal{
    @Override
    public void cry() {
        System.out.println("猫喵喵喵的叫~~~");
    }
}
*/

abstract class Animal{
    public abstract void cry();
}